Overall Objective

Load Libraries

library(tidyverse)
library(cowplot)
library(broom)
library(pwr)
library(plotly)

Import data

#setwd("~/GitHub/time-course/data")
setwd("~/Library/Mobile\ Documents/com~apple~CloudDocs/time-course/data")
rawdata <- "revised_MASTER-ExperimentSummary.csv"
timecourse <- "timecourse2017.csv"
data <- read_csv(rawdata)
tc <- read_csv(timecourse, na = c("","NA"))

Convert data from ‘wide’ to ‘long’ format

data1 <- data %>%
  gather(Sample,Count,2:250)
# Separate samples by identifiers 
data2 <- data1 %>% 
  separate(Sample, into=c("Sample_ID","Dilution_factor","Injection","Tech_rep", sep = "_")) %>% 
  select(-`_`)

Factor the data into categorical variables

# Refactoring Columns for samples
data2$Sample_ID <- as.factor(data2$Sample_ID)
data2$Dilution_factor <- as.numeric(data2$Dilution_factor)
data2$Injection<- as.factor(data2$Injection)
data2$Tech_rep <- as.numeric(data2$Tech_rep)
# Refactoring COlumns for timecourse
tc$Sample_ID <- as.factor(tc$Sample_ID)
tc$Day <- as.factor(tc$Day)
tc$Weight <- as.numeric(tc$Weight)
tc$TEI_Day <- as.factor(tc$TEI_Day)
tc1 <- tc %>% 
  select(Day:Pups)
tc1

Back calculate the original concentration of the sample

data2 <- data2 %>% 
  mutate(True_Count=Dilution_factor*Count)
data2

Average the three technical replicate readings

data3 <- data2 %>% 
  group_by(particle_size,Sample_ID,Dilution_factor,Injection) %>% 
  summarise( tech_N = length(True_Count),
             tech_mean = mean(True_Count),
             tech_sd = sd(True_Count),
             tech_se = tech_sd/sqrt(tech_N))
data3
test1 <- left_join(tc1,data3, by= "Sample_ID")

Summarize samples by injection (average both injections)

data4 <- data3 %>% 
  group_by(particle_size,Sample_ID,Dilution_factor) %>% 
  summarise( inj_N = length(tech_mean),
             inj_mean = mean(tech_mean),
             inj_sd = sd(tech_mean),
             inj_se = inj_sd/sqrt(inj_N))
data4
test2 <- left_join(tc1,data4, by= "Sample_ID")
test2

Quick visualizations

Graphing all samples

test1$Sample_ID_correct = factor(test1$Sample_ID, levels=c('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','70','73','74','75'))
graph1 <- test1 %>%
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se,
                  ymax=tech_mean+tech_se),
                  alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=2.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~ Sample_ID_correct, nrow=7)
graph1

Looking at individual gestational day nanosight line plots

Virgin Mice

test1 %>%
  filter(Day == '1') %>% 
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se,
                  ymax=tech_mean+tech_se),
                  alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=1.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~ Sample_ID_correct)+
  geom_vline(xintercept = 140)+
  annotate("text", x= 235, y = 4E9, label= "140nm")

GD 5.5

test1 %>%
  filter(Day == '5') %>% 
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se,
                  ymax=tech_mean+tech_se),
                  alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=1.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~ Sample_ID_correct)+
  geom_vline(xintercept = 140)+
  annotate("text", x= 235, y = 4E9, label= "140nm")

GD 10.5

test1 %>%
  filter(Day == '10') %>% 
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se,
                  ymax=tech_mean+tech_se),
                  alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=1.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~ Sample_ID_correct)+
  geom_vline(xintercept = 140)+
  annotate("text", x= 235, y = 4E9, label= "140nm")

GD 14.5

test1 %>%
  filter(Day == '14') %>% 
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se,
                  ymax=tech_mean+tech_se),
                  alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=1.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~ Sample_ID_correct)+
  geom_vline(xintercept = 140)+
  annotate("text", x= 235, y = 4E9, label= "140nm")

GD 17.5

test1 %>%
  filter(Day == '17') %>% 
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se,
                  ymax=tech_mean+tech_se),
                  alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=1.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~ Sample_ID_correct)+
  geom_vline(xintercept = 140)+
  annotate("text", x= 235, y = 4E9, label= "140nm")

1 Day Post

test1 %>%
  filter(Day == '20') %>% 
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se,
                  ymax=tech_mean+tech_se),
                  alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=1.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~ Sample_ID_correct)+
  geom_vline(xintercept = 140)+
  annotate("text", x= 235, y = 4E9, label= "140nm")

Graphing averaged samples by experimental day

graph2 <- test2 %>%
  group_by(TEI_Day) %>% 
  ggplot(aes(x=particle_size, y=inj_mean,color=Day ))+ #plot
  #geom_ribbon(aes(ymin=inj_mean-inj_se, ymax=inj_mean+inj_se),alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=2) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Condition")+ #Label table title
  facet_wrap(~ TEI_Day, ncol=7)
graph2

Particle concentration values for each of the 36 samples

test3 <- test2 %>% 
  group_by(Day,Sample_ID) %>% 
  summarise(particle_conc=sum(inj_mean))
test3

Summary statistics of particle concentration (averaging n=6 for each time point)

test4 <- test3 %>% 
  group_by(Day) %>% 
  summarise(Day_N=length(particle_conc),
            Day_mean = mean(particle_conc),
            Day_sd = sd(particle_conc),
            Day_se = Day_sd/sqrt(Day_N))
test4

Boxplot

plot1 <- test3 %>% 
  filter(!Sample_ID %in% c('6','28','32')) %>% 
  group_by(Day) %>% 
  ggplot(aes(x= Day, y = particle_conc, color=Day)) +
  geom_boxplot(colour="black",fill=NA) + 
  geom_point(aes(text = paste("Sample ID:", Sample_ID)),
             position='jitter',size=3)+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition")+ # Label table title
  scale_x_discrete(breaks=c("1","5","10","14","17","20"),  # Change X axis label
                   labels=c("Virgin","5","10","14","17","1 Day Post")) +
  scale_color_discrete(labels=c("Virgin","5","10","14","17","1 Day Post")) # Change Legend
  
plot1

#ggsave("Exosome_plot.png", height = 5, width = 7, units = "in", dpi = 600)

Plotly

  ggplotly(plot1)

Bar plot

plot <- test4 %>% 
  ggplot(aes(x=Day, y=Day_mean, fill=Day ))+ #plot
  geom_col()+
  geom_errorbar(aes(ymin=Day_mean-Day_se, ymax=Day_mean+Day_se), width=.5, 
                size=0.8, colour="black", position=position_dodge(.9)) + #error bars
  scale_y_continuous(expand=c(0,0), breaks = seq(1E11,4E11,1E11))+ #set bottom of graph and scale
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(fill="Condition") + # Label table title
  scale_x_discrete(breaks=c("1","5","10","14","17","20"),  # Change X axis label
                   labels=c("Virgin","5","10","14","17","1 Day Post")) +
  scale_fill_discrete(labels=c("Virgin","5","10","14","17","1 Day Post"))
plot
ggsave("Exosome_barplot.png", height = 5, width = 7, units = "in", dpi = 600)

Looking at Variation between the days the samples were run

test7 <- test3 %>% 
  left_join(tc1)
Joining, by = c("Day", "Sample_ID")
plot2 <- test7 %>%
  ggplot(aes(x = Day, y = particle_conc, color = Day, shape=TEI_Day))+
  geom_point(position= 'dodge',size=4)+
  scale_shape_manual(values=c(15,16,17,18,22,23,24))+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition") + # Label table title
  scale_x_discrete(breaks=c("1","5","10","14","17","20"),  # Change X axis label
                   labels=c("Virgin","5","10","14","17","1 Day Post")) +
  scale_color_discrete(labels=c("Virgin","5","10","14","17","1 Day Post"))
plot2

ggplotly(plot2)
Width not defined. Set with `position_dodge(width = ?)`

Looking at nanoparticle range

nano_100 <- data4 %>% 
  filter(particle_size<140.5)
nano_100_data <- left_join(tc1,nano_100, by= "Sample_ID")
nano_100_data_plot <- nano_100_data %>%
  group_by(Day,Sample_ID) %>% 
  summarise(particle_conc=sum(inj_mean)) %>% 
  filter(!Sample_ID %in% c('6','28','32')) %>% 
  ggplot(aes(factor(Day),particle_conc, color=Day)) +
  geom_boxplot(colour="black",fill=NA) + 
  geom_point(position='jitter',size=3)+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition") + # Label table title
  scale_x_discrete(breaks=c("1","5","10","14","17","20"),  # Change X axis label
                   labels=c("Virgin","5","10","14","17","1 Day Post")) +
  scale_color_discrete(labels=c("Virgin","5","10","14","17","1 Day Post"))
nano_100_data_plot   

NA

Statistics

Shapiro test

tidy(shapiro.test(test3$particle_conc))

p value >0.05 therefore conclude data is normally distributed

ANOVA

jacob <- nano_100_data %>%
   group_by(Day,Sample_ID) %>% 
  summarise(particle_conc=sum(inj_mean)) %>% 
  filter(!Sample_ID %in% c('6','28','32'))
         
fit <- aov(particle_conc ~ Day, data=jacob)
stats <- tidy(fit)
stats

Statistically significant, thus Tukey’s HSD post hoc analysis can determine significant differences.

Tukey Post Hoc Test

HSD <- TukeyHSD(fit)
tukey <- tidy(HSD)
tukey

Significant Tukey Post Hoc Test Values

tukey %>%
  filter(adj.p.value<0.05) %>% 
  arrange(adj.p.value)
test8 <- test7 %>% 
  filter(!Day == "20")
fit <- lm(particle_conc ~ Weight ,data = test8)
summary(fit)

Call:
lm(formula = particle_conc ~ Weight, data = test8)

Residuals:
       Min         1Q     Median         3Q        Max 
-2.600e+11 -7.122e+10 -2.456e+10  8.690e+10  2.239e+11 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)   
(Intercept) 5.768e+10  7.666e+10   0.752  0.45727   
Weight      8.548e+09  2.849e+09   3.000  0.00519 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.127e+11 on 32 degrees of freedom
Multiple R-squared:  0.2196,    Adjusted R-squared:  0.1952 
F-statistic: 9.002 on 1 and 32 DF,  p-value: 0.00519
tidy(summary(fit))
test7 %>% 
  ggplot(aes(x= Weight, y = particle_conc))+
  geom_point()+
  geom_smooth()+
  xlab("\nWeight (g)\n") + # X axis label
  ylab("Exosomes/ml\n") + # Y axis label
  ggtitle("Linear Regression of Exosome \nConcentration vs. Weight")+ #title
  labs(color="Day")#Label table title

NA
test7 %>% 
  filter(!Sample_ID == '70') %>% 
  ggplot(aes(x= Weight, y = particle_conc))+
  geom_point(size = 3,aes(color=factor(Day)))+
  geom_smooth(method = "lm", level = 0.95)+
  xlab("\nWeight (g)\n") + # X axis label
  ylab("Exosomes/ml\n") + # Y axis label
  ggtitle("Linear Regression of Exosome \nConcentration vs. Weight")+ #title
  labs(color="Day")#Label table title

test7 %>% 
  ggplot(aes(x= Pups, y = particle_conc))+
  geom_point(size = 4, aes(color=factor(Day)))+
  #geom_smooth(method = "lm", level = 0.95)+
  scale_x_continuous(breaks=seq(0,12,2))+
  xlab("\nNumbwe of Pups\n") + # X axis label
  ylab("Exosomes/ml\n") + # Y axis label
  ggtitle("Linear Regression of Exosome \nConcentration vs. Number of Pups")+ #title
  labs(color="Day")#Label table title

mean_placenta <- tc %>% 
  filter(Day %in% c('10','14','17') & !Sample_ID %in% c('70','73','74','75')) %>%
  select(-(TEI_Day:Pup_right),-Resorp) %>% 
  gather("Placenta_avg","Plac_weight", 3:5) %>%
  group_by(Day,Sample_ID) %>% 
  summarise(N = length(Plac_weight),
            mean_plac = mean(Plac_weight*1000, na.rm = TRUE), #convert g to mg
            sd = sd(Plac_weight)*1000,  #convert g to mg
            se = sd/sqrt(N))
mean_placenta %>% 
  inner_join(test7) %>% 
  ggplot(aes(x= mean_plac, y = particle_conc))+
  geom_point(size= 3,aes(color=factor(Day)))+
  geom_smooth(method = "lm", level = 0.95)+
  xlab("\nPlacental Weight (mg)\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="G.D.")#Label table title
Joining, by = c("Day", "Sample_ID")
joining factor and character vector, coercing into character vector

mean_placenta %>% 
  inner_join(test7) %>% 
  ggplot(aes(x = Pups, y = particle_conc))+
  geom_point(size= 3,aes(color=factor(Day)))+
  geom_smooth(method = "lm", se= FALSE)+
  facet_wrap(~Day)+
  scale_x_continuous(breaks=seq(1,12,2))+
  xlab("\nNumbr of Pups\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="G.D.")#Label table title
Joining, by = c("Day", "Sample_ID")
joining factor and character vector, coercing into character vector

test3 %>% 
  filter(!Day %in% c('1','20')) %>% 
  group_by(Day) %>% 
  ggplot(aes(factor(Day),particle_conc, color=Day)) +
  geom_point(size=3)+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition")#Label table title

nanosight_plot <- test1 %>%
  filter(Sample_ID == '75') %>% 
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se, ymax=tech_mean+tech_se),alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=1.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size (nm)") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~Injection)
nanosight_plot
ggsave("Nanosight_plot.png", height = 5, width = 7, units = "in", dpi = 600)

 test3 %>% 
  filter(!Sample_ID %in% c('1','6','15','16','19','24','29','6','28','32')) %>% 
  group_by(Day) %>% 
  ggplot(aes(x= Day, y = particle_conc, color=Day)) +
  geom_boxplot(colour="black",fill=NA) + 
  geom_point(aes(text = paste("Sample ID:", Sample_ID)),
             position='jitter',size=3)+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition")+ # Label table title
  scale_x_discrete(breaks=c("1","5","10","14","17","20"),  # Change X axis label
                   labels=c("Virgin","5","10","14","17","1 Day Post")) +
  scale_color_discrete(labels=c("Virgin","5","10","14","17","1 Day Post")) # Change Legend
Ignoring unknown aesthetics: text

 filtered_data <- test3 %>% 
  filter(!Sample_ID %in% c('1','6','15','16','19','24','29','6','28','32'))
filtered_fit <- aov(particle_conc ~ Day, data=filtered_data)
filtered_stats <- tidy(filtered_fit)
filtered_stats
filtered_HSD <- TukeyHSD(filtered_fit)
filtered_tukey <- tidy(filtered_HSD)
filtered_tukey %>% 
  filter(adj.p.value < 0.05) %>% 
  arrange(adj.p.value)
LS0tCnRpdGxlOiAiTmFub3NpZ2h0IEFuYWx5c2lzIgphdXRob3I6ICJTZWFuIE5ndXllbiIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQojT3ZlcmFsbCBPYmplY3RpdmUgCgoKIyNMb2FkIExpYnJhcmllcwoKYGBge3IsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShicm9vbSkKbGlicmFyeShwd3IpCmxpYnJhcnkocGxvdGx5KQpgYGAKCiMjSW1wb3J0IGRhdGEKYGBge3IsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI3NldHdkKCJ+L0dpdEh1Yi90aW1lLWNvdXJzZS9kYXRhIikKc2V0d2QoIn4vTGlicmFyeS9Nb2JpbGVcIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL3RpbWUtY291cnNlL2RhdGEiKQoKcmF3ZGF0YSA8LSAicmV2aXNlZF9NQVNURVItRXhwZXJpbWVudFN1bW1hcnkuY3N2Igp0aW1lY291cnNlIDwtICJ0aW1lY291cnNlMjAxNy5jc3YiCgoKZGF0YSA8LSByZWFkX2NzdihyYXdkYXRhKQp0YyA8LSByZWFkX2Nzdih0aW1lY291cnNlLCBuYSA9IGMoIiIsIk5BIikpCmBgYAoKIyNDb252ZXJ0IGRhdGEgZnJvbSAnd2lkZScgdG8gJ2xvbmcnIGZvcm1hdApgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZGF0YTEgPC0gZGF0YSAlPiUKICBnYXRoZXIoU2FtcGxlLENvdW50LDI6MjUwKQoKIyBTZXBhcmF0ZSBzYW1wbGVzIGJ5IGlkZW50aWZpZXJzIApkYXRhMiA8LSBkYXRhMSAlPiUgCiAgc2VwYXJhdGUoU2FtcGxlLCBpbnRvPWMoIlNhbXBsZV9JRCIsIkRpbHV0aW9uX2ZhY3RvciIsIkluamVjdGlvbiIsIlRlY2hfcmVwIiwgc2VwID0gIl8iKSkgJT4lIAogIHNlbGVjdCgtYF9gKQpgYGAKCiMjRmFjdG9yIHRoZSBkYXRhIGludG8gY2F0ZWdvcmljYWwgdmFyaWFibGVzCgpgYGB7cn0KIyBSZWZhY3RvcmluZyBDb2x1bW5zIGZvciBzYW1wbGVzCmRhdGEyJFNhbXBsZV9JRCA8LSBhcy5mYWN0b3IoZGF0YTIkU2FtcGxlX0lEKQpkYXRhMiREaWx1dGlvbl9mYWN0b3IgPC0gYXMubnVtZXJpYyhkYXRhMiREaWx1dGlvbl9mYWN0b3IpCmRhdGEyJEluamVjdGlvbjwtIGFzLmZhY3RvcihkYXRhMiRJbmplY3Rpb24pCmRhdGEyJFRlY2hfcmVwIDwtIGFzLm51bWVyaWMoZGF0YTIkVGVjaF9yZXApCgoKIyBSZWZhY3RvcmluZyBDT2x1bW5zIGZvciB0aW1lY291cnNlCnRjJFNhbXBsZV9JRCA8LSBhcy5mYWN0b3IodGMkU2FtcGxlX0lEKQp0YyREYXkgPC0gYXMuZmFjdG9yKHRjJERheSkKdGMkV2VpZ2h0IDwtIGFzLm51bWVyaWModGMkV2VpZ2h0KQp0YyRURUlfRGF5IDwtIGFzLmZhY3Rvcih0YyRURUlfRGF5KQpgYGAKCgpgYGB7cn0KdGMxIDwtIHRjICU+JSAKICBzZWxlY3QoRGF5OlB1cHMpCnRjMQpgYGAKCiMjQmFjayBjYWxjdWxhdGUgdGhlIG9yaWdpbmFsIGNvbmNlbnRyYXRpb24gb2YgdGhlIHNhbXBsZQpgYGB7cn0KZGF0YTIgPC0gZGF0YTIgJT4lIAogIG11dGF0ZShUcnVlX0NvdW50PURpbHV0aW9uX2ZhY3RvcipDb3VudCkKZGF0YTIKYGBgCgojIyBBdmVyYWdlIHRoZSB0aHJlZSB0ZWNobmljYWwgcmVwbGljYXRlIHJlYWRpbmdzCmBgYHtyLCBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0V9CmRhdGEzIDwtIGRhdGEyICU+JSAKICBncm91cF9ieShwYXJ0aWNsZV9zaXplLFNhbXBsZV9JRCxEaWx1dGlvbl9mYWN0b3IsSW5qZWN0aW9uKSAlPiUgCiAgc3VtbWFyaXNlKCB0ZWNoX04gPSBsZW5ndGgoVHJ1ZV9Db3VudCksCiAgICAgICAgICAgICB0ZWNoX21lYW4gPSBtZWFuKFRydWVfQ291bnQpLAogICAgICAgICAgICAgdGVjaF9zZCA9IHNkKFRydWVfQ291bnQpLAogICAgICAgICAgICAgdGVjaF9zZSA9IHRlY2hfc2Qvc3FydCh0ZWNoX04pKQpkYXRhMwoKCnRlc3QxIDwtIGxlZnRfam9pbih0YzEsZGF0YTMsIGJ5PSAiU2FtcGxlX0lEIikKYGBgCgoKIyNTdW1tYXJpemUgc2FtcGxlcyBieSBpbmplY3Rpb24gKGF2ZXJhZ2UgYm90aCBpbmplY3Rpb25zKQpgYGB7ciwgd2FybmluZz1GQUxTRX0KCmRhdGE0IDwtIGRhdGEzICU+JSAKICBncm91cF9ieShwYXJ0aWNsZV9zaXplLFNhbXBsZV9JRCxEaWx1dGlvbl9mYWN0b3IpICU+JSAKICBzdW1tYXJpc2UoIGlual9OID0gbGVuZ3RoKHRlY2hfbWVhbiksCiAgICAgICAgICAgICBpbmpfbWVhbiA9IG1lYW4odGVjaF9tZWFuKSwKICAgICAgICAgICAgIGlual9zZCA9IHNkKHRlY2hfbWVhbiksCiAgICAgICAgICAgICBpbmpfc2UgPSBpbmpfc2Qvc3FydChpbmpfTikpCmRhdGE0Cgp0ZXN0MiA8LSBsZWZ0X2pvaW4odGMxLGRhdGE0LCBieT0gIlNhbXBsZV9JRCIpCgp0ZXN0MgoKYGBgCgojUXVpY2sgdmlzdWFsaXphdGlvbnMKCiMjIyBHcmFwaGluZyBhbGwgc2FtcGxlcwpgYGB7ciwgd2FybmluZz1GQUxTRX0KdGVzdDEkU2FtcGxlX0lEX2NvcnJlY3QgPSBmYWN0b3IodGVzdDEkU2FtcGxlX0lELCBsZXZlbHM9YygnMScsJzInLCczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JywnMTAnLCcxMScsJzEyJywnMTMnLCcxNCcsJzE1JywnMTYnLCcxNycsJzE4JywnMTknLCcyMCcsJzIxJywnMjInLCcyMycsJzI0JywnMjUnLCcyNicsJzI3JywnMjgnLCcyOScsJzMwJywnMzEnLCczMicsJzMzJywnMzQnLCczNScsJzM2JywnNzAnLCc3MycsJzc0JywnNzUnKSkKCmdyYXBoMSA8LSB0ZXN0MSAlPiUKICBnZ3Bsb3QoYWVzKHg9cGFydGljbGVfc2l6ZSwgeT10ZWNoX21lYW4sY29sb3I9SW5qZWN0aW9uICkpKyAjcGxvdAogIGdlb21fcmliYm9uKGFlcyh5bWluPXRlY2hfbWVhbi10ZWNoX3NlLAogICAgICAgICAgICAgICAgICB5bWF4PXRlY2hfbWVhbit0ZWNoX3NlKSwKICAgICAgICAgICAgICAgICAgYWxwaGE9MC4yLGZpbGwgPSBhbHBoYSgnZ3JleTEyJywgMC4yKSkgKyAjZXJyb3IgYmFycwogIGdlb21fbGluZShzaXplPTIuMCkgKyB4bGltKDAsNTAwKSsgI2xpbmUgc2l6ZSwgeC1heGlzIHNjYWxlCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpKyAjc2V0IGJvdHRvbSBvZiBncmFwaAogIHhsYWIoIlBhcnRpY2xlIFNpemUiKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5NZWFuIFBhcnRpY2xlIENvbmNlbnRyYXRpb24vbWxcbiIpICsgIyBZIGF4aXMgbGFiZWwKICBnZ3RpdGxlKCJOYW5vc2lnaHQgSGlzdG9ncmFtIG9mXG5WaXJnaW4gTW91c2UgUGxhc21hIikrICN0aXRsZQogIGxhYnMoY29sb3I9IkluamVjdGlvbiIpKyAjTGFiZWwgdGFibGUgdGl0bGUKICBmYWNldF93cmFwKCB+IFNhbXBsZV9JRF9jb3JyZWN0LCBucm93PTcpCgpncmFwaDEKYGBgCgojIyMjTG9va2luZyBhdCBpbmRpdmlkdWFsIGdlc3RhdGlvbmFsIGRheSBuYW5vc2lnaHQgbGluZSBwbG90cyAgCgoqKlZpcmdpbiBNaWNlKioKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnRlc3QxICU+JQogIGZpbHRlcihEYXkgPT0gJzEnKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXBhcnRpY2xlX3NpemUsIHk9dGVjaF9tZWFuLGNvbG9yPUluamVjdGlvbiApKSsgI3Bsb3QKICBnZW9tX3JpYmJvbihhZXMoeW1pbj10ZWNoX21lYW4tdGVjaF9zZSwKICAgICAgICAgICAgICAgICAgeW1heD10ZWNoX21lYW4rdGVjaF9zZSksCiAgICAgICAgICAgICAgICAgIGFscGhhPTAuMixmaWxsID0gYWxwaGEoJ2dyZXkxMicsIDAuMikpICsgI2Vycm9yIGJhcnMKICBnZW9tX2xpbmUoc2l6ZT0xLjApICsgeGxpbSgwLDUwMCkrICNsaW5lIHNpemUsIHgtYXhpcyBzY2FsZQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQ9YygwLDApKSsgI3NldCBib3R0b20gb2YgZ3JhcGgKICB4bGFiKCJQYXJ0aWNsZSBTaXplIikgKyAjIFggYXhpcyBsYWJlbAogIHlsYWIoIlxuTWVhbiBQYXJ0aWNsZSBDb25jZW50cmF0aW9uL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiTmFub3NpZ2h0IEhpc3RvZ3JhbSBvZlxuVmlyZ2luIE1vdXNlIFBsYXNtYSIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJJbmplY3Rpb24iKSsgI0xhYmVsIHRhYmxlIHRpdGxlCiAgZmFjZXRfd3JhcCggfiBTYW1wbGVfSURfY29ycmVjdCkrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMTQwKSsKICBhbm5vdGF0ZSgidGV4dCIsIHg9IDIzNSwgeSA9IDRFOSwgbGFiZWw9ICIxNDBubSIpCmBgYAoKKipHRCA1LjUqKiAgCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp0ZXN0MSAlPiUKICBmaWx0ZXIoRGF5ID09ICc1JykgJT4lIAogIGdncGxvdChhZXMoeD1wYXJ0aWNsZV9zaXplLCB5PXRlY2hfbWVhbixjb2xvcj1JbmplY3Rpb24gKSkrICNwbG90CiAgZ2VvbV9yaWJib24oYWVzKHltaW49dGVjaF9tZWFuLXRlY2hfc2UsCiAgICAgICAgICAgICAgICAgIHltYXg9dGVjaF9tZWFuK3RlY2hfc2UpLAogICAgICAgICAgICAgICAgICBhbHBoYT0wLjIsZmlsbCA9IGFscGhhKCdncmV5MTInLCAwLjIpKSArICNlcnJvciBiYXJzCiAgZ2VvbV9saW5lKHNpemU9MS4wKSArIHhsaW0oMCw1MDApKyAjbGluZSBzaXplLCB4LWF4aXMgc2NhbGUKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkrICNzZXQgYm90dG9tIG9mIGdyYXBoCiAgeGxhYigiUGFydGljbGUgU2l6ZSIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbk1lYW4gUGFydGljbGUgQ29uY2VudHJhdGlvbi9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIk5hbm9zaWdodCBIaXN0b2dyYW0gb2ZcblZpcmdpbiBNb3VzZSBQbGFzbWEiKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iSW5qZWN0aW9uIikrICNMYWJlbCB0YWJsZSB0aXRsZQogIGZhY2V0X3dyYXAoIH4gU2FtcGxlX0lEX2NvcnJlY3QpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDE0MCkrCiAgYW5ub3RhdGUoInRleHQiLCB4PSAyMzUsIHkgPSA0RTksIGxhYmVsPSAiMTQwbm0iKQpgYGAKCgoqKkdEIDEwLjUqKiAgCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp0ZXN0MSAlPiUKICBmaWx0ZXIoRGF5ID09ICcxMCcpICU+JSAKICBnZ3Bsb3QoYWVzKHg9cGFydGljbGVfc2l6ZSwgeT10ZWNoX21lYW4sY29sb3I9SW5qZWN0aW9uICkpKyAjcGxvdAogIGdlb21fcmliYm9uKGFlcyh5bWluPXRlY2hfbWVhbi10ZWNoX3NlLAogICAgICAgICAgICAgICAgICB5bWF4PXRlY2hfbWVhbit0ZWNoX3NlKSwKICAgICAgICAgICAgICAgICAgYWxwaGE9MC4yLGZpbGwgPSBhbHBoYSgnZ3JleTEyJywgMC4yKSkgKyAjZXJyb3IgYmFycwogIGdlb21fbGluZShzaXplPTEuMCkgKyB4bGltKDAsNTAwKSsgI2xpbmUgc2l6ZSwgeC1heGlzIHNjYWxlCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpKyAjc2V0IGJvdHRvbSBvZiBncmFwaAogIHhsYWIoIlBhcnRpY2xlIFNpemUiKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5NZWFuIFBhcnRpY2xlIENvbmNlbnRyYXRpb24vbWxcbiIpICsgIyBZIGF4aXMgbGFiZWwKICBnZ3RpdGxlKCJOYW5vc2lnaHQgSGlzdG9ncmFtIG9mXG5WaXJnaW4gTW91c2UgUGxhc21hIikrICN0aXRsZQogIGxhYnMoY29sb3I9IkluamVjdGlvbiIpKyAjTGFiZWwgdGFibGUgdGl0bGUKICBmYWNldF93cmFwKCB+IFNhbXBsZV9JRF9jb3JyZWN0KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxNDApKwogIGFubm90YXRlKCJ0ZXh0IiwgeD0gMjM1LCB5ID0gNEU5LCBsYWJlbD0gIjE0MG5tIikKYGBgCgoqKkdEIDE0LjUqKiAgCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp0ZXN0MSAlPiUKICBmaWx0ZXIoRGF5ID09ICcxNCcpICU+JSAKICBnZ3Bsb3QoYWVzKHg9cGFydGljbGVfc2l6ZSwgeT10ZWNoX21lYW4sY29sb3I9SW5qZWN0aW9uICkpKyAjcGxvdAogIGdlb21fcmliYm9uKGFlcyh5bWluPXRlY2hfbWVhbi10ZWNoX3NlLAogICAgICAgICAgICAgICAgICB5bWF4PXRlY2hfbWVhbit0ZWNoX3NlKSwKICAgICAgICAgICAgICAgICAgYWxwaGE9MC4yLGZpbGwgPSBhbHBoYSgnZ3JleTEyJywgMC4yKSkgKyAjZXJyb3IgYmFycwogIGdlb21fbGluZShzaXplPTEuMCkgKyB4bGltKDAsNTAwKSsgI2xpbmUgc2l6ZSwgeC1heGlzIHNjYWxlCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpKyAjc2V0IGJvdHRvbSBvZiBncmFwaAogIHhsYWIoIlBhcnRpY2xlIFNpemUiKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5NZWFuIFBhcnRpY2xlIENvbmNlbnRyYXRpb24vbWxcbiIpICsgIyBZIGF4aXMgbGFiZWwKICBnZ3RpdGxlKCJOYW5vc2lnaHQgSGlzdG9ncmFtIG9mXG5WaXJnaW4gTW91c2UgUGxhc21hIikrICN0aXRsZQogIGxhYnMoY29sb3I9IkluamVjdGlvbiIpKyAjTGFiZWwgdGFibGUgdGl0bGUKICBmYWNldF93cmFwKCB+IFNhbXBsZV9JRF9jb3JyZWN0KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxNDApKwogIGFubm90YXRlKCJ0ZXh0IiwgeD0gMjM1LCB5ID0gNEU5LCBsYWJlbD0gIjE0MG5tIikKYGBgCgoKCioqR0QgMTcuNSoqICAKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnRlc3QxICU+JQogIGZpbHRlcihEYXkgPT0gJzE3JykgJT4lIAogIGdncGxvdChhZXMoeD1wYXJ0aWNsZV9zaXplLCB5PXRlY2hfbWVhbixjb2xvcj1JbmplY3Rpb24gKSkrICNwbG90CiAgZ2VvbV9yaWJib24oYWVzKHltaW49dGVjaF9tZWFuLXRlY2hfc2UsCiAgICAgICAgICAgICAgICAgIHltYXg9dGVjaF9tZWFuK3RlY2hfc2UpLAogICAgICAgICAgICAgICAgICBhbHBoYT0wLjIsZmlsbCA9IGFscGhhKCdncmV5MTInLCAwLjIpKSArICNlcnJvciBiYXJzCiAgZ2VvbV9saW5lKHNpemU9MS4wKSArIHhsaW0oMCw1MDApKyAjbGluZSBzaXplLCB4LWF4aXMgc2NhbGUKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkrICNzZXQgYm90dG9tIG9mIGdyYXBoCiAgeGxhYigiUGFydGljbGUgU2l6ZSIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbk1lYW4gUGFydGljbGUgQ29uY2VudHJhdGlvbi9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIk5hbm9zaWdodCBIaXN0b2dyYW0gb2ZcblZpcmdpbiBNb3VzZSBQbGFzbWEiKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iSW5qZWN0aW9uIikrICNMYWJlbCB0YWJsZSB0aXRsZQogIGZhY2V0X3dyYXAoIH4gU2FtcGxlX0lEX2NvcnJlY3QpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDE0MCkrCiAgYW5ub3RhdGUoInRleHQiLCB4PSAyMzUsIHkgPSA0RTksIGxhYmVsPSAiMTQwbm0iKQpgYGAKCgoqKjEgRGF5IFBvc3QqKiAgCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp0ZXN0MSAlPiUKICBmaWx0ZXIoRGF5ID09ICcyMCcpICU+JSAKICBnZ3Bsb3QoYWVzKHg9cGFydGljbGVfc2l6ZSwgeT10ZWNoX21lYW4sY29sb3I9SW5qZWN0aW9uICkpKyAjcGxvdAogIGdlb21fcmliYm9uKGFlcyh5bWluPXRlY2hfbWVhbi10ZWNoX3NlLAogICAgICAgICAgICAgICAgICB5bWF4PXRlY2hfbWVhbit0ZWNoX3NlKSwKICAgICAgICAgICAgICAgICAgYWxwaGE9MC4yLGZpbGwgPSBhbHBoYSgnZ3JleTEyJywgMC4yKSkgKyAjZXJyb3IgYmFycwogIGdlb21fbGluZShzaXplPTEuMCkgKyB4bGltKDAsNTAwKSsgI2xpbmUgc2l6ZSwgeC1heGlzIHNjYWxlCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpKyAjc2V0IGJvdHRvbSBvZiBncmFwaAogIHhsYWIoIlBhcnRpY2xlIFNpemUiKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5NZWFuIFBhcnRpY2xlIENvbmNlbnRyYXRpb24vbWxcbiIpICsgIyBZIGF4aXMgbGFiZWwKICBnZ3RpdGxlKCJOYW5vc2lnaHQgSGlzdG9ncmFtIG9mXG5WaXJnaW4gTW91c2UgUGxhc21hIikrICN0aXRsZQogIGxhYnMoY29sb3I9IkluamVjdGlvbiIpKyAjTGFiZWwgdGFibGUgdGl0bGUKICBmYWNldF93cmFwKCB+IFNhbXBsZV9JRF9jb3JyZWN0KSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxNDApKwogIGFubm90YXRlKCJ0ZXh0IiwgeD0gMjM1LCB5ID0gNEU5LCBsYWJlbD0gIjE0MG5tIikKYGBgCgojIyMgR3JhcGhpbmcgYXZlcmFnZWQgc2FtcGxlcyBieSBleHBlcmltZW50YWwgZGF5CmBgYHtyLCB3YXJuaW5nPUZBTFNFfQpncmFwaDIgPC0gdGVzdDIgJT4lCiAgZ3JvdXBfYnkoVEVJX0RheSkgJT4lIAogIGdncGxvdChhZXMoeD1wYXJ0aWNsZV9zaXplLCB5PWlual9tZWFuLGNvbG9yPURheSApKSsgI3Bsb3QKICAjZ2VvbV9yaWJib24oYWVzKHltaW49aW5qX21lYW4taW5qX3NlLCB5bWF4PWlual9tZWFuK2lual9zZSksYWxwaGE9MC4yLGZpbGwgPSBhbHBoYSgnZ3JleTEyJywgMC4yKSkgKyAjZXJyb3IgYmFycwogIGdlb21fbGluZShzaXplPTIpICsgeGxpbSgwLDUwMCkrICNsaW5lIHNpemUsIHgtYXhpcyBzY2FsZQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQ9YygwLDApKSsgI3NldCBib3R0b20gb2YgZ3JhcGgKICB4bGFiKCJQYXJ0aWNsZSBTaXplIikgKyAjIFggYXhpcyBsYWJlbAogIHlsYWIoIlxuTWVhbiBQYXJ0aWNsZSBDb25jZW50cmF0aW9uL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiTmFub3NpZ2h0IEhpc3RvZ3JhbSBvZlxuVmlyZ2luIE1vdXNlIFBsYXNtYSIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJDb25kaXRpb24iKSsgI0xhYmVsIHRhYmxlIHRpdGxlCiAgZmFjZXRfd3JhcCh+IFRFSV9EYXksIG5jb2w9NykKCmdyYXBoMgpgYGAKIyMjIFBhcnRpY2xlIGNvbmNlbnRyYXRpb24gdmFsdWVzIGZvciBlYWNoIG9mIHRoZSAzNiBzYW1wbGVzCmBgYHtyfQp0ZXN0MyA8LSB0ZXN0MiAlPiUgCiAgZ3JvdXBfYnkoRGF5LFNhbXBsZV9JRCkgJT4lIAogIHN1bW1hcmlzZShwYXJ0aWNsZV9jb25jPXN1bShpbmpfbWVhbikpCnRlc3QzCmBgYAojIyMgU3VtbWFyeSBzdGF0aXN0aWNzIG9mIHBhcnRpY2xlIGNvbmNlbnRyYXRpb24gKGF2ZXJhZ2luZyBuPTYgZm9yIGVhY2ggdGltZSBwb2ludCkKYGBge3J9CnRlc3Q0IDwtIHRlc3QzICU+JSAKICBncm91cF9ieShEYXkpICU+JSAKICBzdW1tYXJpc2UoRGF5X049bGVuZ3RoKHBhcnRpY2xlX2NvbmMpLAogICAgICAgICAgICBEYXlfbWVhbiA9IG1lYW4ocGFydGljbGVfY29uYyksCiAgICAgICAgICAgIERheV9zZCA9IHNkKHBhcnRpY2xlX2NvbmMpLAogICAgICAgICAgICBEYXlfc2UgPSBEYXlfc2Qvc3FydChEYXlfTikpCnRlc3Q0CmBgYAoKIyMjQm94cGxvdApgYGB7ciwgd2FybmluZz1GQUxTRX0KcGxvdDEgPC0gdGVzdDMgJT4lIAogIGZpbHRlcighU2FtcGxlX0lEICVpbiUgYygnNicsJzI4JywnMzInKSkgJT4lIAogIGdyb3VwX2J5KERheSkgJT4lIAogIGdncGxvdChhZXMoeD0gRGF5LCB5ID0gcGFydGljbGVfY29uYywgY29sb3I9RGF5KSkgKwogIGdlb21fYm94cGxvdChjb2xvdXI9ImJsYWNrIixmaWxsPU5BKSArIAogIGdlb21fcG9pbnQoYWVzKHRleHQgPSBwYXN0ZSgiU2FtcGxlIElEOiIsIFNhbXBsZV9JRCkpLAogICAgICAgICAgICAgcG9zaXRpb249J2ppdHRlcicsc2l6ZT0zKSsKICB4bGFiKCJcbkRheSBvZiBHZXN0YXRpb25cbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbkV4b3NvbWVzL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiUGxhc21hIEV4b3NvbWUgQ29uY2VudHJhdGlvblxuVGhyb3VnaG91dCBQcmVnbmFuY3lcbiIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJDb25kaXRpb24iKSsgIyBMYWJlbCB0YWJsZSB0aXRsZQogIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzPWMoIjEiLCI1IiwiMTAiLCIxNCIsIjE3IiwiMjAiKSwgICMgQ2hhbmdlIFggYXhpcyBsYWJlbAogICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIlZpcmdpbiIsIjUiLCIxMCIsIjE0IiwiMTciLCIxIERheSBQb3N0IikpICsKICBzY2FsZV9jb2xvcl9kaXNjcmV0ZShsYWJlbHM9YygiVmlyZ2luIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjEgRGF5IFBvc3QiKSkgIyBDaGFuZ2UgTGVnZW5kCiAgCnBsb3QxCgojZ2dzYXZlKCJFeG9zb21lX3Bsb3QucG5nIiwgaGVpZ2h0ID0gNSwgd2lkdGggPSA3LCB1bml0cyA9ICJpbiIsIGRwaSA9IDYwMCkKCmBgYAoKIyNQbG90bHkKYGBge3J9CiAgZ2dwbG90bHkocGxvdDEpCmBgYAoKCgojIyNCYXIgcGxvdApgYGB7ciwgd2FybmluZz1GQUxTRX0KcGxvdCA8LSB0ZXN0NCAlPiUgCiAgZ2dwbG90KGFlcyh4PURheSwgeT1EYXlfbWVhbiwgZmlsbD1EYXkgKSkrICNwbG90CiAgZ2VvbV9jb2woKSsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPURheV9tZWFuLURheV9zZSwgeW1heD1EYXlfbWVhbitEYXlfc2UpLCB3aWR0aD0uNSwgCiAgICAgICAgICAgICAgICBzaXplPTAuOCwgY29sb3VyPSJibGFjayIsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC45KSkgKyAjZXJyb3IgYmFycwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQ9YygwLDApLCBicmVha3MgPSBzZXEoMUUxMSw0RTExLDFFMTEpKSsgI3NldCBib3R0b20gb2YgZ3JhcGggYW5kIHNjYWxlCiAgeGxhYigiXG5EYXkgb2YgR2VzdGF0aW9uXG4iKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5FeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIlBsYXNtYSBFeG9zb21lIENvbmNlbnRyYXRpb25cblRocm91Z2hvdXQgUHJlZ25hbmN5XG4iKSsgI3RpdGxlCiAgbGFicyhmaWxsPSJDb25kaXRpb24iKSArICMgTGFiZWwgdGFibGUgdGl0bGUKICBzY2FsZV94X2Rpc2NyZXRlKGJyZWFrcz1jKCIxIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjIwIiksICAjIENoYW5nZSBYIGF4aXMgbGFiZWwKICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJWaXJnaW4iLCI1IiwiMTAiLCIxNCIsIjE3IiwiMSBEYXkgUG9zdCIpKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShsYWJlbHM9YygiVmlyZ2luIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjEgRGF5IFBvc3QiKSkKCnBsb3QKCmdnc2F2ZSgiRXhvc29tZV9iYXJwbG90LnBuZyIsIGhlaWdodCA9IDUsIHdpZHRoID0gNywgdW5pdHMgPSAiaW4iLCBkcGkgPSA2MDApCmBgYAoKCiMjI0xvb2tpbmcgYXQgVmFyaWF0aW9uIGJldHdlZW4gdGhlIGRheXMgdGhlIHNhbXBsZXMgd2VyZSBydW4KYGBge3IsIHdhcm5pbmc9RkFMU0V9CnRlc3Q3IDwtIHRlc3QzICU+JSAKICBsZWZ0X2pvaW4odGMxKQoKcGxvdDIgPC0gdGVzdDcgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGF5LCB5ID0gcGFydGljbGVfY29uYywgY29sb3IgPSBEYXksIHNoYXBlPVRFSV9EYXkpKSsKICBnZW9tX3BvaW50KHBvc2l0aW9uPSAnZG9kZ2UnLHNpemU9NCkrCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDE1LDE2LDE3LDE4LDIyLDIzLDI0KSkrCiAgeGxhYigiXG5EYXkgb2YgR2VzdGF0aW9uXG4iKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5FeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIlBsYXNtYSBFeG9zb21lIENvbmNlbnRyYXRpb25cblRocm91Z2hvdXQgUHJlZ25hbmN5XG4iKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iQ29uZGl0aW9uIikgKyAjIExhYmVsIHRhYmxlIHRpdGxlCiAgc2NhbGVfeF9kaXNjcmV0ZShicmVha3M9YygiMSIsIjUiLCIxMCIsIjE0IiwiMTciLCIyMCIpLCAgIyBDaGFuZ2UgWCBheGlzIGxhYmVsCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiVmlyZ2luIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjEgRGF5IFBvc3QiKSkgKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGxhYmVscz1jKCJWaXJnaW4iLCI1IiwiMTAiLCIxNCIsIjE3IiwiMSBEYXkgUG9zdCIpKQoKcGxvdDIKCmBgYAoKYGBge3J9CmdncGxvdGx5KHBsb3QyKQpgYGAKCiNMb29raW5nIGF0IG5hbm9wYXJ0aWNsZSByYW5nZQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbmFub18xMDAgPC0gZGF0YTQgJT4lIAogIGZpbHRlcihwYXJ0aWNsZV9zaXplPDE0MC41KQoKbmFub18xMDBfZGF0YSA8LSBsZWZ0X2pvaW4odGMxLG5hbm9fMTAwLCBieT0gIlNhbXBsZV9JRCIpCgpuYW5vXzEwMF9kYXRhX3Bsb3QgPC0gbmFub18xMDBfZGF0YSAlPiUKICBncm91cF9ieShEYXksU2FtcGxlX0lEKSAlPiUgCiAgc3VtbWFyaXNlKHBhcnRpY2xlX2NvbmM9c3VtKGlual9tZWFuKSkgJT4lIAogIGZpbHRlcighU2FtcGxlX0lEICVpbiUgYygnNicsJzI4JywnMzInKSkgJT4lIAogIGdncGxvdChhZXMoZmFjdG9yKERheSkscGFydGljbGVfY29uYywgY29sb3I9RGF5KSkgKwogIGdlb21fYm94cGxvdChjb2xvdXI9ImJsYWNrIixmaWxsPU5BKSArIAogIGdlb21fcG9pbnQocG9zaXRpb249J2ppdHRlcicsc2l6ZT0zKSsKICB4bGFiKCJcbkRheSBvZiBHZXN0YXRpb25cbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbkV4b3NvbWVzL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiUGxhc21hIEV4b3NvbWUgQ29uY2VudHJhdGlvblxuVGhyb3VnaG91dCBQcmVnbmFuY3lcbiIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJDb25kaXRpb24iKSArICMgTGFiZWwgdGFibGUgdGl0bGUKICBzY2FsZV94X2Rpc2NyZXRlKGJyZWFrcz1jKCIxIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjIwIiksICAjIENoYW5nZSBYIGF4aXMgbGFiZWwKICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJWaXJnaW4iLCI1IiwiMTAiLCIxNCIsIjE3IiwiMSBEYXkgUG9zdCIpKSArCiAgc2NhbGVfY29sb3JfZGlzY3JldGUobGFiZWxzPWMoIlZpcmdpbiIsIjUiLCIxMCIsIjE0IiwiMTciLCIxIERheSBQb3N0IikpCgpuYW5vXzEwMF9kYXRhX3Bsb3QgICAKICAKCmBgYAoKI1N0YXRpc3RpY3MKCgojIyNTaGFwaXJvIHRlc3QKYGBge3J9CnRpZHkoc2hhcGlyby50ZXN0KHRlc3QzJHBhcnRpY2xlX2NvbmMpKQoKYGBgCnAgdmFsdWUgPjAuMDUgdGhlcmVmb3JlIGNvbmNsdWRlIGRhdGEgaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQKCiMjI0FOT1ZBCmBgYHtyfQoKamFjb2IgPC0gbmFub18xMDBfZGF0YSAlPiUKICAgZ3JvdXBfYnkoRGF5LFNhbXBsZV9JRCkgJT4lIAogIHN1bW1hcmlzZShwYXJ0aWNsZV9jb25jPXN1bShpbmpfbWVhbikpICU+JSAKICBmaWx0ZXIoIVNhbXBsZV9JRCAlaW4lIGMoJzYnLCcyOCcsJzMyJykpCiAgICAgICAgIApmaXQgPC0gYW92KHBhcnRpY2xlX2NvbmMgfiBEYXksIGRhdGE9amFjb2IpCnN0YXRzIDwtIHRpZHkoZml0KQpzdGF0cwpgYGAKU3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgdGh1cyBUdWtleSdzIEhTRCBwb3N0IGhvYyBhbmFseXNpcyBjYW4gZGV0ZXJtaW5lIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLgoKIyMjVHVrZXkgUG9zdCBIb2MgVGVzdApgYGB7cn0KSFNEIDwtIFR1a2V5SFNEKGZpdCkKdHVrZXkgPC0gdGlkeShIU0QpCnR1a2V5CmBgYAoKIyMjU2lnbmlmaWNhbnQgVHVrZXkgUG9zdCBIb2MgVGVzdCBWYWx1ZXMKYGBge3J9CnR1a2V5ICU+JQogIGZpbHRlcihhZGoucC52YWx1ZTwwLjA1KSAlPiUgCiAgYXJyYW5nZShhZGoucC52YWx1ZSkKYGBgCgoKCgoKCmBgYHtyfQp0ZXN0OCA8LSB0ZXN0NyAlPiUgCiAgZmlsdGVyKCFEYXkgPT0gIjIwIikKCmZpdCA8LSBsbShwYXJ0aWNsZV9jb25jIH4gV2VpZ2h0ICxkYXRhID0gdGVzdDgpCgpzdW1tYXJ5KGZpdCkKdGlkeShzdW1tYXJ5KGZpdCkpCgoKYGBgCgpgYGB7cn0KdGVzdDcgJT4lIAogIGdncGxvdChhZXMoeD0gV2VpZ2h0LCB5ID0gcGFydGljbGVfY29uYykpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aCgpKwogIHhsYWIoIlxuV2VpZ2h0IChnKVxuIikgKyAjIFggYXhpcyBsYWJlbAogIHlsYWIoIkV4b3NvbWVzL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiTGluZWFyIFJlZ3Jlc3Npb24gb2YgRXhvc29tZSBcbkNvbmNlbnRyYXRpb24gdnMuIFdlaWdodCIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJEYXkiKSNMYWJlbCB0YWJsZSB0aXRsZQoKICAKYGBgCmBgYHtyfQp0ZXN0NyAlPiUgCiAgZmlsdGVyKCFTYW1wbGVfSUQgPT0gJzcwJykgJT4lIAogIGdncGxvdChhZXMoeD0gV2VpZ2h0LCB5ID0gcGFydGljbGVfY29uYykpKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsYWVzKGNvbG9yPWZhY3RvcihEYXkpKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgbGV2ZWwgPSAwLjk1KSsKICB4bGFiKCJcbldlaWdodCAoZylcbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJFeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIkxpbmVhciBSZWdyZXNzaW9uIG9mIEV4b3NvbWUgXG5Db25jZW50cmF0aW9uIHZzLiBXZWlnaHQiKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iRGF5IikjTGFiZWwgdGFibGUgdGl0bGUKCmBgYAoKCmBgYHtyfQp0ZXN0NyAlPiUgCiAgZ2dwbG90KGFlcyh4PSBQdXBzLCB5ID0gcGFydGljbGVfY29uYykpKwogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGFlcyhjb2xvcj1mYWN0b3IoRGF5KSkpKwogICNnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsZXZlbCA9IDAuOTUpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDAsMTIsMikpKwogIHhsYWIoIlxuTnVtYndlIG9mIFB1cHNcbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJFeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIkxpbmVhciBSZWdyZXNzaW9uIG9mIEV4b3NvbWUgXG5Db25jZW50cmF0aW9uIHZzLiBOdW1iZXIgb2YgUHVwcyIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJEYXkiKSNMYWJlbCB0YWJsZSB0aXRsZQpgYGAKCmBgYHtyfQptZWFuX3BsYWNlbnRhIDwtIHRjICU+JSAKICBmaWx0ZXIoRGF5ICVpbiUgYygnMTAnLCcxNCcsJzE3JykgJiAhU2FtcGxlX0lEICVpbiUgYygnNzAnLCc3MycsJzc0JywnNzUnKSkgJT4lCiAgc2VsZWN0KC0oVEVJX0RheTpQdXBfcmlnaHQpLC1SZXNvcnApICU+JSAKICBnYXRoZXIoIlBsYWNlbnRhX2F2ZyIsIlBsYWNfd2VpZ2h0IiwgMzo1KSAlPiUKICBncm91cF9ieShEYXksU2FtcGxlX0lEKSAlPiUgCiAgc3VtbWFyaXNlKE4gPSBsZW5ndGgoUGxhY193ZWlnaHQpLAogICAgICAgICAgICBtZWFuX3BsYWMgPSBtZWFuKFBsYWNfd2VpZ2h0KjEwMDAsIG5hLnJtID0gVFJVRSksICNjb252ZXJ0IGcgdG8gbWcKICAgICAgICAgICAgc2QgPSBzZChQbGFjX3dlaWdodCkqMTAwMCwgICNjb252ZXJ0IGcgdG8gbWcKICAgICAgICAgICAgc2UgPSBzZC9zcXJ0KE4pKQoKbWVhbl9wbGFjZW50YSAlPiUgCiAgaW5uZXJfam9pbih0ZXN0NykgJT4lIAogIGdncGxvdChhZXMoeD0gbWVhbl9wbGFjLCB5ID0gcGFydGljbGVfY29uYykpKwogIGdlb21fcG9pbnQoc2l6ZT0gMyxhZXMoY29sb3I9ZmFjdG9yKERheSkpKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsZXZlbCA9IDAuOTUpKwogIHhsYWIoIlxuUGxhY2VudGFsIFdlaWdodCAobWcpXG4iKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5FeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIlBsYXNtYSBFeG9zb21lIENvbmNlbnRyYXRpb25cblRocm91Z2hvdXQgUHJlZ25hbmN5XG4iKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iRy5ELiIpI0xhYmVsIHRhYmxlIHRpdGxlCgpgYGAKCgpgYGB7cn0KbWVhbl9wbGFjZW50YSAlPiUgCiAgaW5uZXJfam9pbih0ZXN0NykgJT4lIAogIGdncGxvdChhZXMoeCA9IFB1cHMsIHkgPSBwYXJ0aWNsZV9jb25jKSkrCiAgZ2VvbV9wb2ludChzaXplPSAzLGFlcyhjb2xvcj1mYWN0b3IoRGF5KSkpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlPSBGQUxTRSkrCiAgZmFjZXRfd3JhcCh+RGF5KSsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgxLDEyLDIpKSsKICB4bGFiKCJcbk51bWJyIG9mIFB1cHNcbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbkV4b3NvbWVzL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiUGxhc21hIEV4b3NvbWUgQ29uY2VudHJhdGlvblxuVGhyb3VnaG91dCBQcmVnbmFuY3lcbiIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJHLkQuIikjTGFiZWwgdGFibGUgdGl0bGUKYGBgCgoKCmBgYHtyfQp0ZXN0MyAlPiUgCiAgZmlsdGVyKCFEYXkgJWluJSBjKCcxJywnMjAnKSkgJT4lIAogIGdyb3VwX2J5KERheSkgJT4lIAogIGdncGxvdChhZXMoZmFjdG9yKERheSkscGFydGljbGVfY29uYywgY29sb3I9RGF5KSkgKwogIGdlb21fcG9pbnQoc2l6ZT0zKSsKICB4bGFiKCJcbkRheSBvZiBHZXN0YXRpb25cbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbkV4b3NvbWVzL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiUGxhc21hIEV4b3NvbWUgQ29uY2VudHJhdGlvblxuVGhyb3VnaG91dCBQcmVnbmFuY3lcbiIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJDb25kaXRpb24iKSNMYWJlbCB0YWJsZSB0aXRsZQoKCmBgYAoKCgpgYGB7cn0KbmFub3NpZ2h0X3Bsb3QgPC0gdGVzdDEgJT4lCiAgZmlsdGVyKFNhbXBsZV9JRCA9PSAnNzUnKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXBhcnRpY2xlX3NpemUsIHk9dGVjaF9tZWFuLGNvbG9yPUluamVjdGlvbiApKSsgI3Bsb3QKICBnZW9tX3JpYmJvbihhZXMoeW1pbj10ZWNoX21lYW4tdGVjaF9zZSwgeW1heD10ZWNoX21lYW4rdGVjaF9zZSksYWxwaGE9MC4yLGZpbGwgPSBhbHBoYSgnZ3JleTEyJywgMC4yKSkgKyAjZXJyb3IgYmFycwogIGdlb21fbGluZShzaXplPTEuMCkgKyB4bGltKDAsNTAwKSsgI2xpbmUgc2l6ZSwgeC1heGlzIHNjYWxlCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpKyAjc2V0IGJvdHRvbSBvZiBncmFwaAogIHhsYWIoIlBhcnRpY2xlIFNpemUgKG5tKSIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbk1lYW4gUGFydGljbGUgQ29uY2VudHJhdGlvbi9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIk5hbm9zaWdodCBIaXN0b2dyYW0gb2ZcblZpcmdpbiBNb3VzZSBQbGFzbWEiKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iSW5qZWN0aW9uIikrICNMYWJlbCB0YWJsZSB0aXRsZQogIGZhY2V0X3dyYXAoIH5JbmplY3Rpb24pCgpuYW5vc2lnaHRfcGxvdAoKZ2dzYXZlKCJOYW5vc2lnaHRfcGxvdC5wbmciLCBoZWlnaHQgPSA1LCB3aWR0aCA9IDcsIHVuaXRzID0gImluIiwgZHBpID0gNjAwKQpgYGAKCgpgYGB7cn0KCiB0ZXN0MyAlPiUgCiAgZmlsdGVyKCFTYW1wbGVfSUQgJWluJSBjKCcxJywnNicsJzE1JywnMTYnLCcxOScsJzI0JywnMjknLCc2JywnMjgnLCczMicpKSAlPiUgCiAgZ3JvdXBfYnkoRGF5KSAlPiUgCiAgZ2dwbG90KGFlcyh4PSBEYXksIHkgPSBwYXJ0aWNsZV9jb25jLCBjb2xvcj1EYXkpKSArCiAgZ2VvbV9ib3hwbG90KGNvbG91cj0iYmxhY2siLGZpbGw9TkEpICsgCiAgZ2VvbV9wb2ludChhZXModGV4dCA9IHBhc3RlKCJTYW1wbGUgSUQ6IiwgU2FtcGxlX0lEKSksCiAgICAgICAgICAgICBwb3NpdGlvbj0naml0dGVyJyxzaXplPTMpKwogIHhsYWIoIlxuRGF5IG9mIEdlc3RhdGlvblxuIikgKyAjIFggYXhpcyBsYWJlbAogIHlsYWIoIlxuRXhvc29tZXMvbWxcbiIpICsgIyBZIGF4aXMgbGFiZWwKICBnZ3RpdGxlKCJQbGFzbWEgRXhvc29tZSBDb25jZW50cmF0aW9uXG5UaHJvdWdob3V0IFByZWduYW5jeVxuIikrICN0aXRsZQogIGxhYnMoY29sb3I9IkNvbmRpdGlvbiIpKyAjIExhYmVsIHRhYmxlIHRpdGxlCiAgc2NhbGVfeF9kaXNjcmV0ZShicmVha3M9YygiMSIsIjUiLCIxMCIsIjE0IiwiMTciLCIyMCIpLCAgIyBDaGFuZ2UgWCBheGlzIGxhYmVsCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiVmlyZ2luIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjEgRGF5IFBvc3QiKSkgKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGxhYmVscz1jKCJWaXJnaW4iLCI1IiwiMTAiLCIxNCIsIjE3IiwiMSBEYXkgUG9zdCIpKSAjIENoYW5nZSBMZWdlbmQKCgpgYGAKCmBgYHtyfQogZmlsdGVyZWRfZGF0YSA8LSB0ZXN0MyAlPiUgCiAgZmlsdGVyKCFTYW1wbGVfSUQgJWluJSBjKCcxJywnNicsJzE1JywnMTYnLCcxOScsJzI0JywnMjknLCc2JywnMjgnLCczMicpKQoKCmZpbHRlcmVkX2ZpdCA8LSBhb3YocGFydGljbGVfY29uYyB+IERheSwgZGF0YT1maWx0ZXJlZF9kYXRhKQpmaWx0ZXJlZF9zdGF0cyA8LSB0aWR5KGZpbHRlcmVkX2ZpdCkKZmlsdGVyZWRfc3RhdHMKCmZpbHRlcmVkX0hTRCA8LSBUdWtleUhTRChmaWx0ZXJlZF9maXQpCmZpbHRlcmVkX3R1a2V5IDwtIHRpZHkoZmlsdGVyZWRfSFNEKQoKZmlsdGVyZWRfdHVrZXkgJT4lIAogIGZpbHRlcihhZGoucC52YWx1ZSA8IDAuMDUpICU+JSAKICBhcnJhbmdlKGFkai5wLnZhbHVlKQoKCmBgYAoK